﻿//-----------------------------------------------------------------------
// <copyright file="DownloadPreview.cs" company="Sondre Bjellås">
// This software is licensed as Microsoft Public License (Ms-PL).
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using FlickrDownloadr.Services;
using FlickrNet;
using System.Net;
using System.Collections.Generic;
using FlickrDownloadr.Model;
using System.Threading;

namespace FlickrDownloadr
{
    public partial class DownloadPreview : UserControl, IWizardPage
    {
        private Dictionary<string, Photo> _selectedPhotos;
        private ImageList _list;
        private bool _cancelDownload = false;

        private System.Threading.Thread _thread;

        public DownloadPreview()
        {
            InitializeComponent();

            _selectedPhotos = new Dictionary<string, Photo>();

            _list = new ImageList();
            _list.ImageSize = new System.Drawing.Size(75, 75);
            _list.ColorDepth = ColorDepth.Depth32Bit;

            ResetImageList();

            listView1.LargeImageList = _list;
            listView1.SmallImageList = _list;

            comboBoxCount.SelectedIndex = 1;
            comboBoxCount.SelectedIndexChanged += new EventHandler(comboBoxCount_SelectedIndexChanged);

        }

        private void ResetImageList()
        {
            _list.Images.Clear();
            _list.Images.Add(Properties.Resources.Loading);
        }

        void LicenseSelection_SelectedIndexChanged(object sender, EventArgs e)
        {
            ReloadPage();
        }

        public Bitmap Icon
        {
            get { return Properties.Resources.Camera; }
        }

        public event NextDelegate Next;

        public void OnNext()
        {
            if (Next != null)
                Next(this, false);
        }

        public string Title
        {
            get { return Properties.Resources.PagePreviewTitle; }
        }
        public string Description
        {
            get { return Properties.Resources.PagePreviewDescription; }
        }

        internal void LoadPreview()
        {
            LoadPreview(1, GetCount());
        }

        /// <summary>
        /// Used to force a reload of the download preview. This happens when the user has changed their search options.
        /// </summary>
        public void ReloadPage()
        {
            LoadPreview(1, GetCount());
        }

        FlickrNet.Photos _photos;
        int _previousCount;

        private void LoadPreview(long page, int count)
        {
            listView1.Items.Clear();
            _cancelDownload = true;

            //_photos = _flickr.PeopleGetPublicPhotos(PhotoService.Instance.SearchOptions.UserId, count, (int)page, FlickrNet.SafetyLevel.None, FlickrNet.PhotoSearchExtras.All);
            _photos = PhotoService.Instance.Preview((int)page, count, CreativeCommonsButton.Checked);

            labelPage.Text = "of " + _photos.Pages;

            long availablePhotos = _photos.TotalPhotos;

            if (!CreativeCommonsButton.Checked)
            {
                // There seems to be a very weird bug with FlickrNet, if we supply 1 and 1 as parameters
                // to this call, we will get different values than a count of 10. No idea why...
                Photos photosLicensedForDownloading = PhotoService.Instance.Preview((int)page, count, true);

                //Photos photosLicensedForDownloading2 = PhotoService.Instance.Preview(1, 1, true);
                availablePhotos = photosLicensedForDownloading.TotalPhotos;
            }

            labelCount.Text = string.Format("Total {0} photos and {1} licensed for downloading.", _photos.TotalPhotos, availablePhotos);

            if (availablePhotos == 0)
            {
                buttonMoveNext.Enabled = false;
            }
            else
            {
                buttonMoveNext.Enabled = true;
            }

            if (_photos.TotalPhotos == 0)
            {
                buttonMoveNext.Enabled = false;
                return;
            }

            int index = 0;

            foreach (var photo in _photos)
            {
                ListViewItem item = new ListViewItem(new string[] { photo.Title, photo.DateTaken.ToShortDateString(), Utility.AddSpaceBetweenCapitalLetters(photo.License.ToString()), photo.OwnerName, photo.DateUploaded.ToShortDateString() }, 0);
                item.ToolTipText = GetToolTipText(photo);
                item.Tag = photo;

                if (_selectedPhotos.ContainsKey(photo.PhotoId))
                {
                    item.Checked = true;
                }

                listView1.Items.Add(item);

                index++;
            }

            if (_thread != null && _thread.IsAlive)
            {
                while (_thread.IsAlive)
                {
                    Thread.Sleep(100);
                }
            }

            _thread = new Thread(new ThreadStart(ProcessPhotos));
            _cancelDownload = false;
            _thread.Start();

            if (_photos.Pages > _photos.Page)
            {
                NextButton.Enabled = true;
                LastButton.Enabled = true;
            }
            else
            {
                NextButton.Enabled = false;
                LastButton.Enabled = false;
            }

            if (_photos.Page > 1)
            {
                PrevButton.Enabled = true;
                FirstButton.Enabled = true;
            }
            else
            {
                PrevButton.Enabled = false;
                FirstButton.Enabled = false;
            }

            PageSelect.SelectedIndexChanged -= new EventHandler(PageSelect_Click);

            if (count != _previousCount)
            {
                PageSelect.Items.Clear();

                for (int i = 0; i < _photos.Pages; i++)
                {
                    long pageNumber = (long)i + 1;
                    PageSelect.Items.Add(pageNumber);
                }

                PageSelect.SelectedIndex = 0;

                _previousCount = count;
            }

            PageSelect.SelectedItem = (long)_photos.Page;


            PageSelect.SelectedIndexChanged += new EventHandler(PageSelect_Click);
        }

        private void ProcessPhotos()
        {
            WebClient client = new WebClient();

            var ver = System.Environment.Version;

            for(int i = 0; i < _photos.Count; i++)
            {
                if (_cancelDownload)
                {
                    break;
                }

                Photo photo = _photos[i];
                Image image = Image.FromStream(client.OpenRead(photo.SquareThumbnailUrl));

                UpdateThumbnail(image, i);
            }
        }

        delegate void UpdateThumbnailDelegate(Image image, int index);

        private void UpdateThumbnail(Image image, int index)
        {
            // This check on download cancel is important or can lead to dead-lock with the
            // UI-thread waiting.
            if (_cancelDownload)
            {
                return;
            }

            if (InvokeRequired)
            {
                Invoke(new UpdateThumbnailDelegate(UpdateThumbnail), image, index);
                return;
            }

            try
            {
                int imageIndex = _list.Images.Count;
                _list.Images.Add(image);
                listView1.Items[index].ImageIndex = imageIndex;
            }
            catch
            {
            
            }
        }

        private void SetToolTipText(PhotoViewer photoViewer)
        {
            Photo photo = (Photo)photoViewer.Tag;
            string toolTipText = GetToolTipText(photo);
            toolTip.SetToolTip(photoViewer, toolTipText);
        }

        private string GetToolTipText(Photo photo)
        {
            //PhotoLicense license = PhotoLicense.AllRightsReserved;

            string licenseText = string.Concat("Photo License: ", Utility.AddSpaceBetweenCapitalLetters(photo.License.ToString()));

            StringBuilder toolTipText = new StringBuilder();
            toolTipText.AppendLine(licenseText);
            toolTipText.AppendLine(string.Concat("Title: ", photo.Title));
            toolTipText.AppendLine(string.Concat("Date Taken: ", photo.DateTaken));
            toolTipText.AppendLine(string.Concat("Uploaded: ", photo.DateUploaded));
            toolTipText.AppendLine(string.Concat("Media Type: ", photo.Media));
            toolTipText.AppendLine(string.Concat("Owner: ", photo.OwnerName));

            return toolTipText.ToString();
        }

        void picture_DoubleClick(object sender, EventArgs e)
        {
            PictureBox picture = (PictureBox)sender;
            FlickrNet.Photo photo = (FlickrNet.Photo)picture.Tag;
            Help.ShowHelp(this, photo.WebUrl);
        }

        private int GetCount()
        {
            int count = int.Parse(comboBoxCount.Text);
            return count;
        }


        private void comboBoxCount_SelectedIndexChanged(object sender, EventArgs e)
        {
            // If the user changes count of photos, we will reset the page.
            LoadPreview(1, GetCount());
        }

        private void openOriginalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Control c = contextMenuStrip1.SourceControl;

            PictureBox picture = (PictureBox)c;
            FlickrNet.Photo photo = (FlickrNet.Photo)picture.Tag;
            
            if (!string.IsNullOrEmpty(photo.OriginalFormat))
                Help.ShowHelp(this, photo.OriginalUrl);
            else
                Help.ShowHelp(this, photo.LargeUrl);

        }

        private void openPhotoDetailsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Control c = contextMenuStrip1.SourceControl;

            PictureBox picture = (PictureBox)c;
            FlickrNet.Photo photo = (FlickrNet.Photo)picture.Tag;

            Help.ShowHelp(this, photo.WebUrl);
        }

        private void buttonMoveNext_Click(object sender, EventArgs e)
        {

            if (_selectedPhotos.Count > 0)
            {
                List<Photo> filteredPhotos = new List<Photo>();

                foreach (Photo photo in _selectedPhotos.Values)
                {
                    if (photo.License != LicenseType.AllRightsReserved || Program.Debug)
                    {
                        filteredPhotos.Add(photo);
                    }
                }
                
                DialogResult result = MessageBox.Show("You've checked " + _selectedPhotos.Count + " photos of which you are allowed to download " + filteredPhotos.Count  + ", do you want to download only the selected photos?\r\n\r\nChoose Yes to download selected photos, choose No to download everything.", "Download Only Selected Photos?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (result == DialogResult.No)
                {
                    _selectedPhotos.Clear();
                }
                else
                {
                    PhotoService.Instance.SearchOptions.Type = SearchType.Selection;
                    PhotoService.Instance.SelectedPhotos = filteredPhotos.ToArray();
                }
            }

            _cancelDownload = true;

            OnNext();
        }

        private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
        {
            if (e.ColumnIndex == 2)
            {
                e.DrawDefault = true;
            }
            else
            {
                e.DrawDefault = true;
            }
        }

        private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
        {
            e.DrawDefault = true;
        }

        private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
        {
            e.DrawDefault = true;
        }

        private void thumbnailsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            listView1.View = View.LargeIcon;
        }

        private void detailsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            listView1.View = View.Details;
        }

        private void listView1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (listView1.SelectedItems.Count == 0)
            {
                return;
            }

            Photo photo = (Photo)listView1.SelectedItems[0].Tag;

            Help.ShowHelp(this, photo.WebUrl);
        }

        private void CreativeCommonsButton_Click(object sender, EventArgs e)
        {
            ReloadPage();
        }

        private void FirstButton_Click(object sender, EventArgs e)
        {
            LoadPreview(1, GetCount());
        }

        private void PrevButton_Click(object sender, EventArgs e)
        {
            LoadPreview(_photos.Page - 1, GetCount());
        }

        private void NextButton_Click(object sender, EventArgs e)
        {
            LoadPreview(_photos.Page + 1, GetCount());
        }

        private void LastButton_Click(object sender, EventArgs e)
        {
            LoadPreview(_photos.Pages, GetCount());
        }

        private void PageSelect_Click(object sender, EventArgs e)
        {
            int page = int.Parse(PageSelect.Text);
            LoadPreview(page, GetCount());
        }

        private void listView1_ItemCheck(object sender, ItemCheckEventArgs e)
        {
            Photo photo = (Photo)listView1.Items[e.Index].Tag;

            if (e.NewValue == CheckState.Checked)
            {
                if (!_selectedPhotos.ContainsKey(photo.PhotoId))
                {
                    _selectedPhotos.Add(photo.PhotoId, photo);
                }
            }
            else
            {
                _selectedPhotos.Remove(photo.PhotoId);
            }
        }

        private void CheckAllButton_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem item in listView1.Items)
            {
                item.Checked = CheckAllButton.Checked;
            }
        }

        private void backgroundWorkerThumbnails_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {
            //if (e.ProgressPercentage == 100)
            //{
            //    return;
            //}

            //if (_downloadedIndex == 0)
            //{
            //    ResetImageList();
            //}

            //Image img = (Image)e.UserState;

            //_list.Images.Add(img);
            //listView1.Items[_downloadedIndex].ImageIndex = _downloadedIndex + 1;
        
            //_downloadedIndex++;
        }

        private void backgroundWorkerThumbnails_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
        {
            //MessageBox.Show("Download Canceled");
        }
    }
}
